// ======================================================================
// Copyright (C) 2013 Hell-Prototypes. / www.hellprototypes.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// ======================================================================
#ifndef VISION_THREAD_H
#define VISION_THREAD_H

#include <QThread>
#include <QTime>
#include <QMutex>
#include "define.h"

class vision_thread : public QThread
{
    Q_OBJECT

public:
    vision_thread(QObject *parent = 0);
    virtual ~vision_thread();

    bool   set_capture_index(int index = 0);

    double get_capture_property( int property_id );
    int    set_capture_property( int property_id, double value );
    bool   reset_capture_property();

    void loop_run(bool loop)                    { m_loop_run = loop;                    }
    void disp_binary_image(bool binary_image_en){ m_debug_image_en = binary_image_en;   }
    void set_threshold(double threshold)        { m_threshold = threshold;              }
    void set_feeder_zone_size(QSize size);

    QSize get_feeder_zone_size()                { return m_feeder_zone_size;            }
    void  set_part_area(int area)               { m_target_part_area = area;            }
    int   get_part_area()                       { return m_target_part_area;            }
    QSize get_image_size()                      { return QSize(m_image_w, m_image_h);   }
    void  capture_parts_position()              { m_report_parts_position = true;       }
    void  stop_capture_parts_position()         { m_report_parts_position = false;      }
    void  msdelay(int ms)                       { this->msleep(ms);                     }

protected:
     void run();

signals:
    void frame_update(IplImage* frame);
    void parts_position_info(vector<part_t> * parts_pos);
    void camera_image_size(int w, int h);
    void debug_image_update(const char * win_name , IplImage* p_bin_image);

private:
    bool m_loop_run;
    bool m_debug_image_en;

    bool m_report_parts_position;
    vector<part_t> m_parts_position_cache;

    CvCapture* m_pCapture;
    IplImage* m_pFrame;

    int m_image_w;
    int m_image_h;

    CvRect m_roi_gray;
    CvRect m_roi_bin;
    double m_roi_bin_zoom_factor;

    QMutex m_roi_mutex;

    double m_threshold;
    QSize m_feeder_zone_size;
    CvFont m_cvfont;

    int m_target_part_area;

    detected_parts_info_t m_detected_parts_info;

    void find_box(vector<part_t> &parts_pos, IplImage * image);
    void draw_box(CvBox2D &box, IplImage* img);

    double angle( Point pt1, Point pt2, Point pt0 );
    double angle( Point pt0, Point pt1);
    void hole_fill( IplImage * image);
    void draw_part_flag( IplImage * image, const vector<part_t>& parts_pos );
    void draw_feeder_zone( IplImage * image);
};

#endif // VISION_THREAD_H
